using System;
using System.ComponentModel;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Data;
using System.Configuration;
using Microsoft.SharePoint.Administration;
using System.Xml;
using System.Web;
//using Microsoft.SharePoint.Portal.WebControls;
using System.Net;
using System.IO;
using KbWorksBlogMigrationtool.wss2007SiteData;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.Workflow;

namespace KbWorksBlogMigrationtool
{
    class ListItemsProxy2010
    {
        AppSettingsReader conf = new AppSettingsReader();
        Logging log = new Logging();
        private SPField GetField(SPList list, string name)
        {
            SPField field = null;
            try
            {
                field = list.Fields.GetFieldByInternalName(name);
            }
            catch { }
            try
            {
                field = list.Fields.GetField(name);
            }
            catch { }
            return field;
        }
        public string CreateItems(XmlNode oldItems, string url, string listName, int baseType, string oldUrl)
        {
            int colums = 0;

            SPSite site = new SPSite(url);//http://MySite:12345
            site.AllowUnsafeUpdates = true;

            SPWeb web = site.OpenWeb();//makes connection and opens the site to allow modification

            web.AllowUnsafeUpdates = true;
            SPList list = web.Lists[listName];

            SPListItemCollection listItems = web.Lists[listName].Items;
            SPListItem item = listItems.Add();
            bool documentlib = false;
            XmlNodeList oldItem = Util.RunXPathQuery(oldItems, "//z:row");
            try
            {
                log.append("Count old Columns= " + listName + "  " + oldItem[0].Attributes.Count, 4, "List");
                while (colums < oldItem[0].Attributes.Count)
                {
                    string columnName = oldItem[0].Attributes[colums].LocalName;
                    //if (baseType == 4 && columnName=="ows_Author")
                    //{
                    //    item["Created By"] = oldItem[0].Attributes[colums].Value;
                    //}

                    if (columnName.StartsWith("ows_"))
                    {
                        columnName = columnName.Substring(4);

                        //if (columnName.ToLower()=="title" & baseType==0)
                        //{
                        //    item["ContentTypeId"] = oldItem[0].Attributes[colums].Value;
                        //}

                        SPField field = GetField(list, columnName);

                        //columnName = columnName.Substring(4);

                        if (columnName == "FileRef")
                        {
                            if (listName != "Posts" && listName != "Comments" && listName != "Links")
                            {
                                //plaatje ophalen en opnieuw plaatsen.
                                string fileUrl = string.Empty;

                                fileUrl = oldItem[0].Attributes[colums].Value.Substring(oldItem[0].Attributes[colums].Value.LastIndexOf("#") + 1);
                                if (fileUrl.Contains(".") == false)
                                {
                                    //retrieve items 
                                    string subFolderName = fileUrl.Substring(fileUrl.LastIndexOf(@"/") + 1);
                                    XmlNode items = null;
                                    XmlNodeList subItem = null;
                                    ListItemsitedata2010 subitems = new ListItemsitedata2010(oldUrl, listName);
                                    ArrayList arr = null;
                                    arr = subitems.GetSubItems(listName, Convert.ToString(conf.GetValue("OldPortal", typeof(string))) + @"/" + oldItem[0].Attributes[colums].Value.Substring(oldItem[0].Attributes[colums].Value.LastIndexOf("#") + 1));//,subFolderName);
                                    //create folder
                                    //list.Folders.Add(subFolderName,SPFileSystemObjectType.Folder);
                                    //list.Update();
                                    SPListItem newListItem;
                                    newListItem = list.Folders.Add("", SPFileSystemObjectType.Folder, subFolderName);
                                    newListItem.Update();



                                    // web.Folders.Add(listName + @"/" + subFolderName);
                                    int file = 0;
                                    //add items
                                    if (arr != null)
                                    {
                                        try
                                        {
                                            //SPList list = web.Lists[listName];

                                            SPListItemCollection folderColl = list.Folders;

                                            for (int i = 0; i < folderColl.Count; i++)
                                            {
                                                if (folderColl[i].Name == subFolderName)
                                                {

                                                    while (file < arr.Count)
                                                    {
                                                        string FileName = string.Empty;
                                                        string sfile = string.Empty;
                                                        sfile = arr[file].ToString();
                                                        sfile = sfile.Substring(sfile.LastIndexOf(@"/") + 1);
                                                        FileName = DownloadPicture(fileUrl + @"/" + sfile);
                                                        StreamReader reader = new StreamReader(FileName);
                                                        byte[] DownloadFile = new byte[reader.BaseStream.Length];
                                                        reader.BaseStream.Read(DownloadFile, 0, Convert.ToInt32(reader.BaseStream.Length));
                                                        SPFolder DocumentLibraryFolder = folderColl[i].Folder;

                                                        //do no longer use url in first comment of add() just use the filename..
                                                        SPFile NewFile = DocumentLibraryFolder.Files.Add(sfile, DownloadFile, true);

                                                        reader.Close();
                                                        reader.Dispose();
                                                        File.Delete(FileName);
                                                        file++;

                                                    }
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            log.append("Error Adding multiple files " + ex.ToString(), 4, "Error");
                                        }
                                    }
                                    colums++;
                                    continue;

                                }
                                else
                                {
                                    try
                                    {
                                        if ("Categories" != listName)
                                        {
                                            string FileName = string.Empty;

                                            FileName = DownloadPicture(fileUrl);

                                            StreamReader reader = new StreamReader(FileName);

                                            try
                                            {

                                                SPFolder DocumentLibraryFolder = web.Folders[listName];

                                                SPFile NewFile = DocumentLibraryFolder.Files.Add(url + @"/" + listName + fileUrl.Substring(fileUrl.LastIndexOf(@"/")), reader.BaseStream);
                                                documentlib = true;
                                            }
                                            catch
                                            {
                                                documentlib = false;

                                            }
                                            if (documentlib == false)
                                            {
                                                byte[] DownloadFile = new byte[reader.BaseStream.Length];
                                                reader.BaseStream.Read(DownloadFile, 0, Convert.ToInt32(reader.BaseStream.Length));
                                                item.Attachments.Add(fileUrl.Substring(fileUrl.LastIndexOf(@"/") + 1), DownloadFile);
                                            }
                                            reader.Close();
                                            reader.Dispose();
                                            File.Delete(FileName);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        log.append("Error Adding files to document library " + ex.ToString(), 4, "Error");
                                    }

                                    colums++;
                                    continue;
                                }
                            }
                        }
                        if (field != null)
                        {

                            if (field.ReadOnlyField == false)
                            {
                                switch (field.Type)
                                {
                                    case SPFieldType.Attachments:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Attachment", 4, "List");
                                        if (oldItem[0].Attributes[colums].Value != "0")
                                        {
                                            //getattachments
                                            ListItemsProxy2007 listItemsAttach = new ListItemsProxy2007(oldUrl, listName);
                                            XmlNode attachments = null;
                                            XmlNodeList attach = null;
                                            int a = 0;
                                            attachments = listItemsAttach.GetAttachments(listName, oldItem[0].Attributes["ows_ID"].Value);
                                            if (attachments != null)
                                            {
                                                try
                                                {
                                                    attach = Util.RunXPathQuery(attachments, "//sp:Attachment");
                                                    while (a < attach.Count)
                                                    {
                                                        string FileName = string.Empty;

                                                        FileName = DownloadPicture(attach[a].InnerText);
                                                        StreamReader reader = new StreamReader(FileName);
                                                        byte[] DownloadFile = new byte[reader.BaseStream.Length];
                                                        reader.BaseStream.Read(DownloadFile, 0, Convert.ToInt32(reader.BaseStream.Length));
                                                        item.Attachments.Add(attach[a].InnerText.Substring(attach[a].InnerText.LastIndexOf(@"/") + 1), DownloadFile);

                                                        reader.Close();
                                                        reader.Dispose();
                                                        File.Delete(FileName);
                                                        a++;
                                                    }
                                                }
                                                catch (Exception ex)
                                                {
                                                    log.append("Error Adding attachmentitems " + ex.ToString(), 4, "Error");
                                                }
                                            }
                                            //item[columnName] = oldItem[0].Attributes[colums].Value;
                                        }


                                        break;
                                    case SPFieldType.Boolean:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Boolean", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.AllDayEvent:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type AlldayEvent", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.Calculated:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Calculated", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.Choice:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Choice", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.Computed:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Computed", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.ContentTypeId:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type ContentTypeID", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.Counter:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Count", 4, "List");
                                        item[columnName] = Convert.ToInt32(oldItem[0].Attributes[colums].Value);
                                        break;
                                    case SPFieldType.CrossProjectLink:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type CrossProjectLink", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.Currency:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Currency", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.DateTime:


                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Datetime", 4, "List");
                                        item[columnName] = Convert.ToDateTime(oldItem[0].Attributes[colums].Value);

                                        break;

                                    case SPFieldType.Error:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Error", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.File:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type File", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.GridChoice:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type GridChoice", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        if (baseType == 0)
                                        {
                                            item.Update();
                                        } break;
                                    case SPFieldType.Guid:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Guid", 4, "List");
                                        item[columnName] = new System.Guid(oldItem[0].Attributes[colums].Value);

                                        break;
                                    case SPFieldType.Integer:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Integer", 4, "List");
                                        item[columnName] = Convert.ToInt32(oldItem[0].Attributes[colums].Value);

                                        break;
                                    case SPFieldType.Invalid:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Invalid", 4, "List");
                                        if (oldItem[0].Attributes[colums].Value.Contains(@"#"))
                                        {
                                            item[columnName] = oldItem[0].Attributes[colums].Value.Substring(oldItem[0].Attributes[colums].Value.LastIndexOf(@"#") + 1);
                                        }
                                        else
                                        {
                                            item[columnName] = oldItem[0].Attributes[colums].Value;
                                        }
                                        break;
                                    case SPFieldType.Lookup:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Lookup", 4, "List");
                                        string lookup = string.Empty;
                                        switch (columnName)
                                        {
                                            case "Categories":
                                                //search value in new list..
                                                lookup = SearchItem(oldItem[0].Attributes[colums].Value, web.Lists[columnName]);
                                                item[columnName] = lookup;
                                                item["Category"] = lookup;
                                                break;
                                            case "PostTitle":
                                                //search value in new list..
                                                lookup = SearchItem(oldItem[0].Attributes[colums].Value, web.Lists["Posts"]);
                                                item[columnName] = lookup;

                                                break;
                                            default:
                                                item[columnName] = oldItem[0].Attributes[colums].Value;
                                                break;
                                        }
                                        break;
                                    case SPFieldType.MaxItems:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Maxitems", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.ModStat:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type ModStat", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.MultiChoice:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type MultiChoice", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.Note:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Note", 4, "List");
                                        if (columnName.ToLower() == "body")
                                        {
                                            if (oldItem[0].Attributes[colums].Value.Contains("Photos"))
                                            {
                                                string body = oldItem[0].Attributes[colums].Value;
                                                item[columnName] = body.Replace("Lists/Photos/", "Photos/");
                                            }
                                            else
                                            {
                                                item[columnName] = oldItem[0].Attributes[colums].Value;
                                            }
                                        }
                                        else
                                        {
                                            item[columnName] = oldItem[0].Attributes[colums].Value;
                                        }
                                        break;
                                    case SPFieldType.Number:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Number", 4, "List");
                                        if (columnName == "viewed")
                                        {
                                            item[columnName] = oldItem[0].Attributes[colums].Value.ToString().Substring(0, oldItem[0].Attributes[colums].Value.ToString().IndexOf("."));
                                        }
                                        else
                                        {

                                            item[columnName] = Convert.ToDouble(oldItem[0].Attributes[colums].Value);
                                        }
                                        break;
                                    case SPFieldType.PageSeparator:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type PageSeparator", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.Recurrence:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Recurrence", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.Text:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Text", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.ThreadIndex:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Threadindex", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.Threading:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Threading", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.URL:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Url", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                    case SPFieldType.User:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type User", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.WorkflowEventType:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type WorkflowEventType", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;
                                        break;
                                    case SPFieldType.WorkflowStatus:
                                        log.append("old Column add= " + listName + "  " + oldItem[0].Attributes[colums].Value + " type Workflowstatus", 4, "List");
                                        item[columnName] = oldItem[0].Attributes[colums].Value;

                                        break;
                                }
                            }

                        }

                    }
                    //item[columnName] = oldItem[0].Attributes[colums].Value;

                    colums++;
                }
                if (list.BaseTemplate == SPListTemplateType.Announcements)
                {
                    if (oldItem[0].Attributes["ows_Expires"].Value == null)
                    {
                        item["Expires"] = DateTime.Now;
                    }
                }
                if (baseType != 1)
                {
                    item.Update();
                }
             
            }
            catch (Exception ex)
            {
                log.append("Error Adding items " + ex.ToString(), 4, "Error");
                //Console.WriteLine("Error Adding items " + ex.ToString());
            }

            return "";
        }
       

        public string SearchItem(string oldValue, SPList list)
        {
            StringBuilder builder = new StringBuilder();
            string returnvalue = string.Empty;
            Boolean moreitems = false;
            try
            {

                SPQuery query = new SPQuery();
                query.Query = string.Format(
                "<Query><Where><Contains><FieldRef Name='Title' /><Value Type='Text'>{0}</Value></Contains></Where></Query>", oldValue);
                SPListItemCollection collListItems = list.GetItems(query);
                foreach (SPListItem oListItem in collListItems)
                {
                    if (oldValue.Contains(oListItem["Title"].ToString()))
                    {
                        if (moreitems)
                        {
                            builder.Append(";#");
                            builder.Append(oListItem["ID"].ToString() + @";#" + oListItem["Title"].ToString());

                        }
                        else
                        {
                            builder.Append(oListItem["ID"].ToString() + @";#" + oListItem["Title"].ToString());
                            if (list.Title != "Posts")
                            {
                                moreitems = true;
                            }
                            else
                            {
                                break;
                            }
                        }


                    }
                }
                returnvalue = builder.ToString();
            }
            catch (Exception ex)
            {
                returnvalue = "";
            }
            return returnvalue;
        }
        public string DownloadPicture(string Fileurl)
        {
            string newUrl = string.Empty;
            if (Fileurl.Contains("http") == false)
            {
                newUrl = Convert.ToString(conf.GetValue("OldPortal", typeof(string))) + @"/" + Fileurl;
            }
            else
            {
                newUrl = Fileurl;
            }
            string fileName = "C:\\temp\\" + Guid.NewGuid().ToString();
            System.Net.WebClient client = new System.Net.WebClient();
            client.Credentials = new NetworkCredential(Convert.ToString(conf.GetValue("networkuser", typeof(string))),
                 Convert.ToString(conf.GetValue("networkpass", typeof(string))),
                 Convert.ToString(conf.GetValue("domain", typeof(string))));
            client.DownloadFile(newUrl, fileName);
            return fileName;
            //request.InputStream;


        }
    }
}
